package com.shen.shennetwork

import android.Manifest
import android.content.Context
import android.net.wifi.WifiInfo
import com.shen.shennetwork.WifiUtil
import android.net.wifi.WifiManager
import androidx.core.app.ActivityCompat
import android.content.pm.PackageManager
import android.net.wifi.WifiConfiguration
import android.net.wifi.WifiNetworkSpecifier
import android.util.Log
import android.widget.Toast

class WifiUtil {


    companion object {
        const val TAG = "WifiUtil"

        // 单例
        val ins = WifiUtil()
    }

    fun printCurWifiInfo() {
        if (mWifiManager == null)
            return

        val wifiInfo = mWifiManager!!.connectionInfo
        Log.i(TAG, "cur wifi = " + wifiInfo.ssid)
        Log.i(TAG, "cur getNetworkId = " + wifiInfo.networkId)
    }

    private var mWifiManager: WifiManager? = null
    fun init(context: Context) {
        mWifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager
    }

    /**
     * 切换到指定wifi -- 需要权限android.permission.CHANGE_WIFI_STATE
     * @param wifiName  指定的wifi名字
     * @param wifiPwd   wifi密码，如果已经保存过密码，可以传入null
     * @return
     */
    fun changeToWifi(context: Context, wifiName: String, wifiPwd: String): Boolean {
        if (mWifiManager == null) {
            Log.i(TAG, " ***** init first ***** ")
            return false
        }
        val __wifiName__ = "\"" + wifiName + "\""
        printCurWifiInfo()
        if (ActivityCompat.checkSelfPermission(
                context,
                Manifest.permission.ACCESS_FINE_LOCATION
            ) != PackageManager.PERMISSION_GRANTED
        ) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            Log.i(TAG, "Manifest.permission.ACCESS_FINE_LOCATION")
            return false
        }

        // mWifiManager!!.connectionInfo
        val wifiList: List<*> = mWifiManager!!.configuredNetworks
        Log.i(TAG, "wifiList.size:${wifiList.size}")
        val bFindInList = false
        for (i in wifiList.indices) {
            val wifiInfo0 = wifiList[i] as WifiConfiguration

            Log.i(TAG, "for (i in wifiList.indices) -- __wifiName__:${wifiInfo0.SSID} -- wifiName:${wifiName}")

            // 先找到对应的wifi
            if (__wifiName__ == wifiInfo0.SSID || wifiName == wifiInfo0.SSID) {
                // 1、 先启动，可能已经输入过密码，可以直接启动
                Log.i(TAG, " set wifi 1 = " + wifiInfo0.SSID)
                return doChange2Wifi(context, wifiInfo0.networkId)
            }
        }

        val resultList = mWifiManager!!.scanResults
        for (result in resultList) {
            Log.i(TAG, "for (result in resultList) -- result.SSID:${result.SSID} -- wifiName:${wifiName}")
            if (result.SSID == __wifiName__ || result.SSID == wifiName){


                // 注意configuredNetworks中的ssid，系统源码中加上了双引号，这里比对的时候要去掉
                val config = mWifiManager!!.configuredNetworks.singleOrNull { it.SSID.replace("\"", "") == wifiName }
                if(config != null)
                    return doChange2Wifi(context, config.networkId)
                else{

                }
            }
        }

        // 2、如果wifi还没有输入过密码，尝试输入密码，启动wifi
        if (!bFindInList) {
            val wifiNewConfiguration = createWifiInfo(wifiName, wifiPwd) //使用wpa2的wifi加密方式
            val newNetworkId = mWifiManager!!.addNetwork(wifiNewConfiguration)
            if (newNetworkId == -1) {
                //Log.e(TAG, "操作失败,需要您到手机wifi列表中取消对设备连接的保存");
                Toast.makeText(context, "操作失败,需要您到手机wifi列表中取消对设备连接的保存", Toast.LENGTH_SHORT).show()
            } else {
                return doChange2Wifi(context, newNetworkId)
            }
        }
        return false
    }

    private fun doChange2Wifi(context: Context, newNetworkId: Int): Boolean {
        // 如果wifi权限没打开（1、先打开wifi，2，使用指定的wifi
        if (!mWifiManager!!.isWifiEnabled) {
            mWifiManager!!.isWifiEnabled = true
        }
        val enableNetwork = mWifiManager!!.enableNetwork(newNetworkId, true)
        return if (!enableNetwork) {
            //Log.e(TAG, "切换到指定wifi失败");
            Toast.makeText(context, "切换到指定wifi失败", Toast.LENGTH_SHORT).show()
            false
        } else {
            //Log.e(TAG, "切换到指定wifi成功");
            Toast.makeText(context, "切换到指定wifi成功", Toast.LENGTH_SHORT).show()
            true
        }
    }

    /**
     * 创建 WifiConfiguration，这里创建的是wpa2加密方式的wifi
     *
     * @param ssid     wifi账号
     * @param password wifi密码
     * @return
     */
    private fun createWifiInfo(ssid: String, password: String): WifiConfiguration {
        val config = WifiConfiguration()
        config.allowedAuthAlgorithms.clear()
        config.allowedGroupCiphers.clear()
        config.allowedKeyManagement.clear()
        config.allowedPairwiseCiphers.clear()
        config.allowedProtocols.clear()
        config.SSID = "\"" + ssid + "\""
        config.preSharedKey = "\"" + password + "\""
        config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN)
        config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP)
        config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP)
        config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK)
        config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP)
        config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP)
        config.allowedProtocols.set(WifiConfiguration.Protocol.RSN)
        config.allowedProtocols.set(WifiConfiguration.Protocol.WPA)
        config.status = WifiConfiguration.Status.ENABLED
        return config
    }

    /**
     * 创建一个「WifiConfig」
     */
    private fun createWifiConfig(context: Context, ssid: String, password: String, type: WifiCapability): WifiConfiguration {
        //初始化WifiConfiguration
        val config = WifiConfiguration()
        if (ActivityCompat.checkSelfPermission(
                context,
                Manifest.permission.ACCESS_FINE_LOCATION
            ) != PackageManager.PERMISSION_GRANTED
        ) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return config
        }

        config.allowedAuthAlgorithms.clear()
        config.allowedGroupCiphers.clear()
        config.allowedKeyManagement.clear()
        config.allowedPairwiseCiphers.clear()
        config.allowedProtocols.clear()

        config.SSID = "\"" + ssid + "\""                // 指定对应的SSID


        // 如果之前有类似的配置
        val tempConfig = mWifiManager!!.configuredNetworks.singleOrNull { it -> it.SSID == "\"$ssid\"" }
        if (tempConfig != null) {
            // 则清除·旧有配置  不是自己创建的network 这里其实是删不掉的
            mWifiManager!!.removeNetwork(tempConfig.networkId)
            mWifiManager!!.saveConfiguration()
        }

        // 不需要密码的场景
        when (type) {
            WifiCapability.WIFI_CIPHER_NO_PASS -> {
                config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE)     // 以WEP加密的场景
            }
            WifiCapability.WIFI_CIPHER_WEP -> {  // 以WPA加密的场景，自己测试时，发现热点以WPA2建立时，同样可以用这种配置连接
                config.hiddenSSID = true
                config.wepKeys[0] = "\"" + password + "\""
                config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN)
                config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED)
                config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE)
                config.wepTxKeyIndex = 0
            }
            WifiCapability.WIFI_CIPHER_WPA -> {
                config.preSharedKey = "\"" + password + "\""
                config.hiddenSSID = true
                config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN)
                config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP)
                config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK)
                config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP)
                config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP)
                config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP)
                config.status = WifiConfiguration.Status.ENABLED
            }
        }

        return config
    }


    private fun getCipherType(capabilities: String): WifiCapability {
        return when {
            capabilities.contains("WEB") -> WifiCapability.WIFI_CIPHER_WEP
            capabilities.contains("PSK") -> WifiCapability.WIFI_CIPHER_WPA
            capabilities.contains("WPS") -> WifiCapability.WIFI_CIPHER_NO_PASS
            else -> WifiCapability.WIFI_CIPHER_NO_PASS
        }
    }
}

enum class WifiCapability {
    WIFI_CIPHER_WEP, WIFI_CIPHER_WPA, WIFI_CIPHER_NO_PASS
}